package com.nsharmon.dao.entity;

import java.util.List;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Transient;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.nsharmon.l18n.L18n;
import com.nsharmon.webapp.listeners.HibernateSessionListener;

@Entity
@DiscriminatorValue("container")
public class ContainerAxiom extends Axiom { 
	public enum ContainerVariant {
		Default,
		HasVariant
	}
	
	public ContainerAxiom() {
		setVariant(ContainerVariant.Default);
	}

	@Override
	@Transient
	public String toString() {
		return toString(getVariant());
	}
	
	@Transient
	public String toString(Enum<?> variant) {
		StringBuilder sb = new StringBuilder();
		List<EntityObject> entities = getEntities();
		for(int i=1; i<entities.size(); i++) {
			sb.append(entities.get(i));
			if(i + 1 < entities.size()) {
				sb.append(", ");
			}
		}
		return L18n.getMessage(getClass(), variant.toString(), entities.get(0), sb.toString());
	}

	@Transient
	public EntityObject getContainer() {
		return getEntities().get(0);
	}

	@Transient
	public void setContainer(EntityObject container) {
		if(getEntities().size() == 0) {
			getEntities().add(container);
		} else {
			getEntities().set(0, container);
		}
	}
	
	@Transient
	public EntityObject getContained() {
		return getEntities().get(1);
	}
	
	@Transient
	public void setContained(EntityObject containedAxiom) {
		if(getEntities().size() <= 1) {
			if(getEntities().size() == 0) {
				getEntities().add(null);
			}
			getEntities().add(containedAxiom);
		} else {
			getEntities().set(1, containedAxiom);
		}
	}
	
	@Transient
	public static ContainerAxiom contains(Project project, ContainerVariant variant, String container, String contained, String ... params ) {
		return contains(null, project, variant, container, contained, params);
	}
	
	@Transient
	public static ContainerAxiom contains(Session session, Project project, ContainerVariant variant, String container, String contained, String ... params) {
		ContainerAxiom axiom = null;
		boolean localSession = false;
		Transaction trx = null;
		if(session == null) {
			localSession = true;
			session = HibernateSessionListener.openSession();
			trx = session.beginTransaction();
		}
		
		try {
			axiom = new ContainerAxiom();
			axiom.setProject(project);
			axiom.setVariant(variant);
			project.getAxioms().add(axiom);
			
			EntityObject containerEntity = EntityObject.getOrCreate(session, container);
			axiom.getEntities().add(containerEntity);
			
			EntityObject containedEntity = EntityObject.getOrCreate(session, contained);
			axiom.getEntities().add(containedEntity);
			
			for(String param : params) {
				Parameter parameter = new Parameter(param);
				axiom.getParameters().add(parameter);
			}
			session.update(project);
			
			if(localSession) {
				trx.commit();
			}
		} catch(HibernateException e) {
			axiom = null;
			
			if(localSession) {
				trx.rollback();
			}
			throw e;
		} finally {
			if(localSession) {
				session.close();
			}
		}
		return axiom;		
	}
}
